package jd.client.impl;

import java.io.IOException;
import java.util.List;

import jd.client.JDClient;
import jd.client.Request;
import jd.client.Response;
import jd.client.ResponseFactory;
import jd.client.action.ActionAddLinksGrabberRequest;
import jd.client.action.ActionPauseRequest;
import jd.client.action.ActionReconnectRequest;
import jd.client.action.ActionRestartRequest;
import jd.client.action.ActionShutdownRequest;
import jd.client.action.ActionStartRequest;
import jd.client.action.ActionStopRequest;
import jd.client.action.ActionToggleRequest;
import jd.client.action.ActionUpdateRequest;
import jd.client.exception.ResponseParseException;
import jd.client.get.GetConfigResponse;
import jd.client.get.GetDownloadStatusResponse;
import jd.client.get.GetDownloadsAllCountResponse;
import jd.client.get.GetDownloadsAllListResponse;
import jd.client.get.GetDownloadsCurrentCountResponse;
import jd.client.get.GetDownloadsCurrentListResponse;
import jd.client.get.GetDownloadsFinishedCountResponse;
import jd.client.get.GetDownloadsFinishedListResponse;
import jd.client.get.GetIPResponse;
import jd.client.get.GetIsReconnectResponse;
import jd.client.get.GetRCVersionResponse;
import jd.client.get.GetRandomIPResponse;
import jd.client.get.GetSpeedLimitResponse;
import jd.client.get.GetSpeedResponse;
import jd.client.get.GetVersionResponse;
import jd.client.get.JDGet;
import jd.client.help.HelpRequest;
import jd.client.help.HelpResponse;
import jd.entity.Config;
import jd.entity.DownloadPackage;

/**
 * @author Denis Migol
 * 
 */
public abstract class JDClientBase implements JDClient {

	private final String host;
	private final int port;

	/**
	 * The constructor
	 */
	public JDClientBase() {
		this(DEFAULT_HOST, DEFAULT_PORT);
	}

	/**
	 * 
	 * @param host
	 */
	public JDClientBase(final String host) {
		this(host, DEFAULT_PORT);
	}

	/**
	 * 
	 * @param port
	 */
	public JDClientBase(final int port) {
		this(DEFAULT_HOST, port);
	}

	/**
	 * 
	 * @param host
	 * @param port
	 */
	public JDClientBase(final String host, final int port) {
		super();
		this.host = host;
		this.port = port;
	}

	/**
	 * @return the host
	 */
	@Override
	public String getHost() {
		return host;
	}

	/**
	 * @return the port
	 */
	@Override
	public int getPort() {
		return port;
	}

	/**
	 * 
	 * @return "http://" + host + ":" + port;
	 */
	protected String getHttpPrefix() {
		return "http://" + host + ":" + port;
	}

	/**
	 * 
	 * @param request
	 * @return
	 */
	protected String createUrl(final Request request) {
		return getHttpPrefix() + request.getUrl();
	}

	/**
	 * 
	 * @param request
	 * @return
	 */
	protected String createUrl(final String request) {
		return getHttpPrefix() + request;
	}

	/**
	 * 
	 * @param url
	 * @return
	 * @throws IOException
	 */
	protected abstract String requestToString(String url) throws IOException;

	@Override
	public Response execute(final Request request) throws ResponseParseException, IOException {
		final Response response = ResponseFactory.getResponse(request);
		return response.parse(requestToString(createUrl(request)));
	}

	@Override
	public Response execute(final String request) throws ResponseParseException, IOException {
		final Response response = ResponseFactory.getResponse(request);
		return response.parse(requestToString(createUrl(request)));
	}

	@Override
	public HelpResponse help() throws ResponseParseException, IOException {
		return (HelpResponse) execute(new HelpRequest());
	}

	// ------------------------------------------------------------
	// Get Values:

	@Override
	public String getSpeed() throws ResponseParseException, IOException {
		return ((GetSpeedResponse) execute(JDGet.GET_SPEED)).getSpeed();
	}

	@Override
	public String getIP() throws ResponseParseException, IOException {
		return ((GetIPResponse) execute(JDGet.GET_IP)).getIP();
	}

	@Override
	public String getRandomIP() throws ResponseParseException, IOException {
		return ((GetRandomIPResponse) execute(JDGet.GET_RANDOM_IP)).getIP();
	}

	@Override
	public Config getConfig() throws ResponseParseException, IOException {
		// TODO
		return ((GetConfigResponse) execute(JDGet.GET_CONFIG)).getConfig();
	}

	@Override
	public String getVersion() throws ResponseParseException, IOException {
		return ((GetVersionResponse) execute(JDGet.GET_VERSION)).getVersion();
	}

	@Override
	public String getRCVersion() throws ResponseParseException, IOException {
		return ((GetRCVersionResponse) execute(JDGet.GET_RC_VERSION)).getVersion();
	}

	@Override
	public String getSpeedLimit() throws ResponseParseException, IOException {
		return ((GetSpeedLimitResponse) execute(JDGet.GET_SPEED_LIMIT)).getSpeedLimit();
	}

	@Override
	public Boolean getIsReconnect() throws ResponseParseException, IOException {
		return ((GetIsReconnectResponse) execute(JDGet.GET_IS_RECONNECT)).getReconnect();
	}

	@Override
	public Integer getDownloadStatus() throws ResponseParseException, IOException {
		return ((GetDownloadStatusResponse) execute(JDGet.GET_DOWNLOAD_STATUS)).getStatus();
	}

	@Override
	public Integer getDownloadsCurrentCount() throws ResponseParseException, IOException {
		return ((GetDownloadsCurrentCountResponse) execute(JDGet.GET_DOWNLOADS_CURRENT_COUNT)).getCount();
	}

	@Override
	public List<DownloadPackage> getDownloadsCurrentList() throws ResponseParseException, IOException {
		// TODO
		return ((GetDownloadsCurrentListResponse) execute(JDGet.GET_DOWNLOADS_CURRENT_LIST)).getDownloads();
	}

	@Override
	public Integer getDownloadsAllCount() throws ResponseParseException, IOException {
		return ((GetDownloadsAllCountResponse) execute(JDGet.GET_DOWNLOADS_ALL_COUNT)).getCount();
	}

	@Override
	public List<DownloadPackage> getDownloadsAllList() throws ResponseParseException, IOException {
		// TODO
		return ((GetDownloadsAllListResponse) execute(JDGet.GET_DOWNLOADS_ALL_LIST)).getDownloads();
	}

	@Override
	public Integer getDownloadsFinishedCount() throws ResponseParseException, IOException {
		return ((GetDownloadsFinishedCountResponse) execute(JDGet.GET_DOWNLOADS_FINISHED_COUNT)).getCount();
	}

	@Override
	public List<DownloadPackage> getDownloadsFinishedList() throws ResponseParseException, IOException {
		// TODO
		return ((GetDownloadsFinishedListResponse) execute(JDGet.GET_DOWNLOADS_FINISHED_LIST)).getDownloads();
	}

	// ------------------------------------------------------------
	// Actions:

	@Override
	public String actionStart() throws ResponseParseException, IOException {
		return execute(new ActionStartRequest()) + "";
	}

	@Override
	public String actionPause() throws ResponseParseException, IOException {
		return execute(new ActionPauseRequest()) + "";
	}

	@Override
	public String actionStop() throws ResponseParseException, IOException {
		return execute(new ActionStopRequest()) + "";
	}

	@Override
	public String actionToggle() throws ResponseParseException, IOException {
		return execute(new ActionToggleRequest()) + "";
	}

	@Override
	public String actionUpdate(final boolean force) throws ResponseParseException, IOException {
		return execute(new ActionUpdateRequest().setForce(force)) + "";
	}

	@Override
	public String actionReconnect() throws ResponseParseException, IOException {
		return execute(new ActionReconnectRequest()) + "";
	}

	@Override
	public String actionRestart() throws ResponseParseException, IOException {
		return execute(new ActionRestartRequest()) + "";
	}

	@Override
	public String actionShutdown() throws ResponseParseException, IOException {
		return execute(new ActionShutdownRequest()) + "";
	}

	@Override
	public void actionSetDownloadLimit() {
		// TODO
		throw new UnsupportedOperationException("Not implement yet");
	}

	@Override
	public void actionSetDownloadMax() {
		// TODO
		throw new UnsupportedOperationException("Not implement yet");
	}

	@Override
	public String actionAddLinksGrabber(final boolean grabber, final boolean start, final List<String> links)
			throws Exception {
		return execute(new ActionAddLinksGrabberRequest().setGrabber(grabber).setStart(start).addLinks(links)) + "";
	}

	@Override
	public void actionAddContainerGrabber() {
		// TODO
		throw new UnsupportedOperationException("Not implement yet");
	}

	@Override
	public void actionSaveContainer() {
		// TODO
		throw new UnsupportedOperationException("Not implement yet");
	}

	@Override
	public void actionSetReconnectEnabled(final boolean enabled) {
		// TODO
		throw new UnsupportedOperationException("Not implement yet");
	}

	@Override
	public void actionSetPremiumEnabled(final boolean enabled) {
		// TODO
		throw new UnsupportedOperationException("Not implement yet");
	}

}
